home *** CD-ROM | disk | FTP | other *** search
/ NetNews Offline 2 / NetNews Offline Volume 2.iso / news / comp / lang / c++-part1 / 9050 < prev    next >
Encoding:
Text File  |  1996-08-05  |  6.6 KB  |  280 lines

  1. Newsgroups: comp.lang.c++
  2. Path: tday.slip.netcom.com!user
  3. From: tday@netcom.com (Tony Day)
  4. Subject: Help with bizzare bug (Long)
  5. Message-ID: <tday-2702962256130001@tday.slip.netcom.com>
  6. Sender: netnews@mork.netcom.com
  7. Nntp-Posting-Host: tday.slip.netcom.com
  8. Organization: NETCOM On-line Communication Services (408 261-4700 guest)
  9. Date: Wed, 28 Feb 1996 05:56:13 GMT
  10.  
  11. I am working through the Prata book to teach myself C++ and I have come
  12. across a bizzarre bug in my atempt to do one of the problems.  The
  13. conseuence of the bug is that after a certain line of code, "\n" is
  14. treated as the string "Smiley"!! (Using Symantec 7.0 Mac)
  15.  
  16. The offending function is an overloaded assignment operator:
  17.  
  18. >NameAr & NameAr::operator=(const NameAr & a)
  19. >{
  20. >    if (this == &a)      // if object assigned to self,
  21. >      return *this;  // don't change anything
  22. >   ArrayDb::operator=(a);
  23. >   delete [] name;
  24. >   name = new char[strlen(a.name)+1];
  25. >   strcpy(name, a.name);
  26. >   return *this;
  27. >}
  28.  
  29. and the offending statement is "delete [] name" (if it is removed the
  30. program runs as wriiten)
  31.  
  32. I suspect that this is one delete too many, but cannot see why.  If anyone
  33. else can, please let me know.  Complete code follows.
  34.  
  35. Thanks v.very much
  36.  
  37. Tony
  38.  
  39.  
  40. HEADER FILE FOR BASE AND DERIVED CLASS
  41.  
  42. // arraydb.h -- define array class
  43. #ifndef _ARRAYDB_H_
  44. #define _ARRAYDB_H_
  45. #include <iostream.h>
  46. #include <string.h>
  47.  
  48. class ArrayDb
  49. {
  50. private:
  51.    unsigned int size;         // number of array elements
  52. protected:
  53.    double * arr;                       // address of first element
  54. public:
  55.    ArrayDb();                          // default constructor
  56.    // create an ArrayDb of n elements, set each to val
  57.    ArrayDb(unsigned int n, double val = 0.0);
  58.    // create an ArrayDb of n elements, initialize to array pn
  59.    ArrayDb(const double * pn, unsigned int n);
  60.    ArrayDb(const ArrayDb & a);         // copy constructor
  61.    virtual ~ArrayDb();                         // destructor
  62.    unsigned int arsize() const {return size;}   // returns array size
  63. // overloaded operators
  64.    virtual double & operator[](int i);       // array indexing
  65.    virtual const double & operator[](int i) const; // array indexing (no =)
  66.    virtual ArrayDb & operator=(const ArrayDb & a);
  67.    friend ostream & operator<<(ostream & os, const ArrayDb & a);
  68. };
  69.  
  70. class NameAr: public ArrayDb
  71. {
  72. protected:
  73.    char * name;
  74. public:
  75.    NameAr();                         // default constructor
  76.    // create an ArrayDb of n elements, set each to val
  77.    NameAr(unsigned int n, double val = 0.0, char * n = "Smiley");
  78.    // create an ArrayDb of n elements, initialize to array pn
  79.    NameAr(const double * pn, unsigned int n, char * n = "Smiley");
  80.    NameAr(const ArrayDb & a);
  81.    NameAr(const NameAr & a);         // copy constructor
  82.    ~NameAr();                         // destructor
  83.    NameAr & operator=(const NameAr & a);
  84.    void setname(const char* a);
  85.    friend ostream & operator<<(ostream & os, const NameAr & a);
  86. }; 
  87.  
  88. #endif
  89.  
  90. CLASS METHODS FOR BASE AND DERIVED CLASS
  91.  
  92.  arraydb.cpp -- ArrayDb class methods
  93. #include <iostream.h>
  94. #include <stdlib.h>   // exit() prototype
  95. #include "12_2arraydb.h"
  96.  
  97. // default constructor -- no arguments
  98. ArrayDb::ArrayDb()
  99. {
  100.    arr = NULL;
  101.    size = 0;
  102. }
  103.  
  104. // constructs array of n elements, each set to val
  105. ArrayDb::ArrayDb(unsigned int n, double val)
  106. {  
  107.    arr = new double[n];
  108.    size = n;
  109.    for (int i = 0; i < size; i++)
  110.        arr[i] = val;
  111. }
  112.  
  113. // initialize ArrayDb object to a non-class array
  114. ArrayDb::ArrayDb(const double *pn, unsigned int n)
  115. {  
  116.    arr = new double[n];
  117.    size = n;
  118.    for (int i = 0; i < size; i++)
  119.        arr[i] = pn[i];
  120. }
  121.  
  122. // initialize ArrayDb object to another ArrayDb object
  123. ArrayDb::ArrayDb(const ArrayDb & a)
  124. {  
  125.    size = a.size;
  126.    arr = new double[size];
  127.    for (int i = 0; i < size; i++)
  128.        arr[i] = a.arr[i];
  129. }
  130.  
  131. ArrayDb::~ArrayDb()
  132. {  
  133.    delete [] arr;
  134. }
  135.  
  136. // let user access elements by index (assignment allowed)
  137. double & ArrayDb::operator[](int i)
  138. {
  139.    // check index before continuing
  140.    if (i < 0 || i >= size)
  141.    {
  142.       cerr << "Error in array limits: "
  143.          << i << " is a bad index\n";
  144.       exit(1);
  145.    }
  146.    return arr[i];
  147. }
  148.  
  149. // let user access elements by index (assignment disallowed)
  150. const double & ArrayDb::operator[](int i) const
  151. {
  152.    // check index before continuing
  153.    if (i < 0 || i >= size)
  154.    {
  155.       cerr << "Error in array limits: "
  156.          << i << " is a bad index\n";
  157.       exit(1);
  158.    }
  159.    return arr[i];
  160. }
  161.  
  162. // define class assignment
  163. ArrayDb & ArrayDb::operator=(const ArrayDb & a)
  164. {
  165.    if (this == &a)      // if object assigned to self,
  166.       return *this;  // don't change anything
  167.    delete arr;
  168.    size = a.size;
  169.    arr = new double[size];
  170.    for (int i = 0; i < size; i++)
  171.        arr[i] = a.arr[i];
  172.    return *this;
  173. }
  174.  
  175. // quick output, 5 values to a line
  176. ostream & operator<<(ostream & os, const ArrayDb & a)
  177. {
  178.    for (int i = 0; i < a.size; i++)
  179.    {
  180.        os << a.arr[i] << " ";
  181.        if (i % 5 == 4)
  182.            os << "\n";
  183.    }
  184.    if (i % 5 != 0)
  185.        os << "\n";
  186.    return os;
  187. }
  188.  
  189.    
  190. NameAr::NameAr()
  191.    name = new char[strlen("Smiley")+1];
  192.    name = "Smiley";
  193. }     
  194.  
  195. NameAr::NameAr(unsigned int n, double val, char * m): ArrayDb(n, val)
  196. {  
  197.    name = new char[strlen(m)+1];
  198.    strcpy(name,m);
  199. }  
  200.  
  201. NameAr::NameAr(const double * pn, unsigned int n, char * m ): ArrayDb(pn, n)
  202. {
  203.    name = new char[strlen(m)+1];
  204.    strcpy(name,m);
  205. }
  206.  
  207. NameAr::NameAr(const ArrayDb & a): ArrayDb(a)
  208. {
  209.    name = new char[strlen("Smiley")+1];
  210.    name = "Smiley";
  211. }     
  212.  
  213. NameAr::NameAr(const NameAr & a)
  214. {
  215.    ArrayDb::ArrayDb(a);
  216.    name = new char[strlen(a.name)+1];
  217.    strcpy(name,a.name);
  218. }  
  219.  
  220. NameAr::~NameAr()
  221. {
  222.    delete [] name;
  223. }
  224.  
  225. NameAr & NameAr::operator=(const NameAr & a)
  226. {
  227.     if (this == &a)      // if object assigned to self,
  228.       return *this;  // don't change anything
  229.    ArrayDb::operator=(a);
  230.  
  231.    delete [] name;
  232.    
  233.    name = new char[strlen(a.name)+1];
  234.    
  235.    strcpy(name, a.name);
  236.    return *this;
  237. }
  238.  
  239. void NameAr::setname(const char* a)
  240. {
  241.    delete [] name;
  242.    name = new char[strlen(a)+1];
  243.    strcpy(name, a);
  244. }
  245.  
  246. ostream & operator<<(ostream & os, const NameAr & a)
  247.    os << ArrayDb(a);
  248.    os << a.name;
  249.    os << "\n";
  250.    return os;
  251. }
  252.  
  253. MAIN PROGRAM
  254.  
  255. //ouze12_2main.cpp for 12.2 
  256.  
  257. #include <iostream.h>
  258. #include "12_2arraydb.h"
  259. const int SZ = 5;
  260. int main(void)
  261. {
  262.    double it[SZ] = {19.0, 20.0, 18.0, 16.0, 18.5};
  263.    ArrayDb ita(it, SZ);
  264.    cout << "Displaying an ArrayDb object:\n";
  265.    cout << ita;
  266.    NameAr itna(ita);  //default name
  267.    cout << "Displaying a NameAr object:\n";
  268.    cout << itna;
  269.    NameAr aldo(2 * SZ, 13.2, "Aldo");
  270.    for (int i = 0; i<2*SZ; i++)  // check []
  271.       aldo[i] = aldo[i] + i/2.0;
  272.    cout << aldo; 
  273.    itna = aldo; //check assignment
  274.    cout << itna;
  275.  
  276.       return 0;
  277. }
  278.